﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace WowTourGuideTranslator
{
    /// <summary>
    /// parses wowhead for a given quest
    /// </summary>
    [Serializable]
    public class WowheadItemParser : WowheadBaseParser
    {
        #region fields

        #endregion fields

        #region constructor

        /// <summary>
        /// Initializes a new instance of the <see cref="WowheadItemParser"/> class.
        /// </summary>
        public WowheadItemParser()
        {

        }

        /// <summary>
        /// Initializes a new instance of the <see cref="QuestParser"/> class.
        /// </summary>
        /// <param name="itemId">The item id.</param>
        /// <param name="language">The language.</param>
        private WowheadItemParser(int itemId, string language)
            : base(RequestType.Item, itemId, language)
        {

        }

        #endregion constructor

        #region methods

        /// <summary>
        /// Parses wowhead for the specified quest id.
        /// </summary>
        /// <param name="itemId">The item id.</param>
        /// <param name="language">The language.</param>
        /// <returns></returns>
        internal static WowheadItemParser Parse(int itemId, string language)
        {
            WowheadItemParser itemParser = new WowheadItemParser(itemId, language);

            if (!DataProvider.ItemDict.ContainsKey(itemId))
            {
                DataProvider.ItemDict.Add(itemId, itemParser);
            }

            return itemParser;
        }

        /// <summary>
        /// Parses the pages.
        /// </summary>
        protected override void ParsePages()
        {
            this.Drops = new SerializableDictionary<int, TranslatedWowheadData>();

            base.ParsePages();

            // handle the quest specific details
            this.ParseItemData();
        }

        /// <summary>
        /// Parses the item data.
        /// </summary>
        private void ParseItemData()
        {
            // get details from the wowhead page
            SerializableDictionary<int, TranslatedWowheadData> details = GetWowheadQuestDetails(this.originalPage);
            SerializableDictionary<int, TranslatedWowheadData> transDetails = GetWowheadQuestDetails(this.transPage);

            // create objectives out of the detail info
            foreach (TranslatedWowheadData detail in details.Values)
            {
                if (!transDetails.ContainsKey(detail.Id))
                {
                    continue;
                }

                TranslatedWowheadData transDetail = transDetails[detail.Id];

                detail.Name.Language = DataProvider.DataLanguage;
                detail.Name.Translated = transDetail.Name.Original;

                // add translation 
                if (!DataProvider.TranslationsDict.ContainsKey(detail.Name.Original))
                    DataProvider.TranslationsDict.Add(detail.Name.Original, detail.Name.Translated);

                if (!this.Drops.ContainsKey(detail.Id))
                {
                    this.Drops.Add(detail.Id, detail);
                }
            }
        }

        /// <summary>
        /// Gets the wowhead quest details.
        /// </summary>
        /// <param name="pageContent">Content of the page.</param>
        /// <returns>A dictionary with all details, if nothing found an empty dict</returns>
        private SerializableDictionary<int, TranslatedWowheadData> GetWowheadQuestDetails(string pageContent)
        {
            SerializableDictionary<int, TranslatedWowheadData> returnVal = new SerializableDictionary<int, TranslatedWowheadData>();

            string lootList = this.GetLootlist(pageContent);

            if (lootList != string.Empty)
            {
                string regex = @"\{id:(?<id>\d+),name:'(?<name>[^']+)'[^}]+\}";

                MatchCollection matches = Regex.Matches(lootList, regex, RegexOptions.IgnoreCase);

                foreach (Match match in matches)
                {
                    TranslatedWowheadData matchDetail = this.HandleDetailMatch(match);
                    returnVal.Add(matchDetail.Id, matchDetail);
                }
            }

            return returnVal;
        }

        /// <summary>
        /// Handles the detail match.
        /// </summary>
        /// <param name="match">The match.</param>
        /// <returns></returns>
        private TranslatedWowheadData HandleDetailMatch(Match match)
        {
            return new TranslatedWowheadData()
            {
                Type = RequestType.Npc,
                Id = Convert.ToInt32(match.Groups[@"id"].Value),
                Name = new TranslatedPair() { Original = match.Groups[@"name"].Value },
            };
        }

        /// <summary>
        /// Gets the itemlist from the pages content.
        /// </summary>
        /// <param name="pageContent">Content of the page.</param>
        /// <returns>Itemlist html if found otherwise <seealso cref="string.Empty"/></returns>
        private string GetLootlist(string pageContent)
        {
            string regex = @"new Listview.+dropped-by.+Listview\.funcBox\.initLootTable, data: \[(?<loot>.+)\]\}\);";
            // this is safe because nobody returns null on failure
            return Regex.Match(pageContent, regex, RegexOptions.IgnoreCase | RegexOptions.Multiline).Groups[@"loot"].Value;
        }

        #endregion methods

        #region properties

        /// <summary>
        /// Gets or sets the Drops.
        /// </summary>
        /// <value>The Drops.</value>
        public SerializableDictionary<int, TranslatedWowheadData> Drops { get; set; }

        #endregion properties

     }
}
